package data;

import java.io.Serializable;
import java.util.List;
import java.util.Vector;
import javax.persistence.*;

/**
 *
 * @author Michal Hanzlik, Tomas Jiran
 */
/*
 create table Film (
 id_filmu             INT4                 not null,
 id_osoby             INT4                 not null,
 nazev_filmu          VARCHAR(256)         not null,
 nazev_orig           VARCHAR(256)         null,
 rok                  INT4                 not null,
 delka                INT4                 null,
 ohodnoceni           INT4                 null,
 constraint PK_FILM primary key (id_filmu)
 );
 */
@Entity
@Table(name = "film")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "TYPE_FILM", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue(value = "FILM")
public class Film implements Serializable {

    /**
     * id_filmu INT4 not null
     */
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "film_id_filmu_seq")
    @Column(unique = true, nullable = false)
    private int id_filmu;

    /**
     * rok INT4 not null,
     */
    @Column(nullable = false)
    private int rok;

    /**
     * nazev_filmu VARCHAR(256) not null,
     */
    @Column(nullable = false, columnDefinition = "varchar(256)")
    private String nazev_filmu;

    /**
     * nazev_orig VARCHAR(256) null,
     */
    @Column(columnDefinition = "varchar(256)")
    private String nazev_orig;

    /**
     * delka INT4 null,
     */
    @Column()
    private int delka;

    /**
     * ohodnoceni INT4 null,
     */
    @Column()
    private int ohodnoceni;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_osoby")
    private Uzivatel owner;

    @OneToMany(mappedBy = "film")
    private List<Komentar> komentare;

    @ManyToMany
    @JoinTable( name = "hral_ve",
    joinColumns = {
        @JoinColumn(name = "id_filmu", referencedColumnName = "id_filmu")},
    inverseJoinColumns = {
        @JoinColumn(name = "id_osoby", referencedColumnName = "id_osoby")})
    private List<Herec> herci;

    @ManyToMany
    @JoinTable( name = "natocil",
    joinColumns = {
        @JoinColumn(name = "id_filmu", referencedColumnName = "id_filmu")},
    inverseJoinColumns = {
        @JoinColumn(name = "id_osoby", referencedColumnName = "id_osoby")})
    private List<Reziser> reziseri;

    @ManyToMany
    @JoinTable( name = "pochazi_ze",
    joinColumns = {
        @JoinColumn(name = "id_filmu", referencedColumnName = "id_filmu")},
    inverseJoinColumns = {
        @JoinColumn(name = "id_statu", referencedColumnName = "id_statu")})
    private List<Stat> staty;

    @ManyToMany
    @JoinTable( name = "je_zarazen_do",
    joinColumns = {
        @JoinColumn(name = "id_filmu", referencedColumnName = "id_filmu")},
    inverseJoinColumns = {
        @JoinColumn(name = "id_zanru", referencedColumnName = "id_zanru")})
    private List<Zanr> zanry;

    @OneToMany(mappedBy = "film")
    public List<Hodnoceni> hodnotici_uzivatele;

    public Film() {     // podle JPA2 musi entita mit konstruktor bez parametru
    }

    public Film(int ID, String nazev, int rok) {
        this.id_filmu = ID;
        this.rok = rok;
        this.nazev_filmu = nazev;
    }

    public int getId_filmu() {
        return id_filmu;
    }

    public int getRok() {
        return rok;
    }

    /**
     * Natvavuje rok instance filmu.
     *
     * @param rok Rok výroby filmu.
     * @throws Exception Obyčejná vyjímka při zadání záporného roku.
     */
    public void setRok(int rok) throws Exception {
        if (rok < 0) {
            throw new Exception("Zaporny rok");
        }
        this.rok = rok;
    }

    public String getNazev_filmu() {
        return nazev_filmu;
    }

    public void setNazev_filmu(String nazev_filmu) {
        this.nazev_filmu = nazev_filmu;
    }

    public String getNazev_orig() {
        return nazev_orig;
    }

    public void setNazev_orig(String nazev_orig) {
        this.nazev_orig = nazev_orig;
    }

    public int getDelka() {
        return delka;
    }

    public void setDelka(int delka) throws Exception {
        if (delka < 0) {
            throw new Exception("Zaporna delka");
        }
        this.delka = delka;
    }

    public int getOhodnoceni() {
        return ohodnoceni;
    }

    public void setOhodnoceni(int hodnoceni) {
        this.ohodnoceni = hodnoceni;
    }

    public void setKomentare(List<Komentar> komentare) {
        this.komentare = komentare;
    }

    public List<Komentar> getKomentare() {
        return komentare;
    }

    /**
     * Uživatel, který vkládá film.
     */
    public void setOwner(Uzivatel owner) {
        this.owner = owner;
    }

    public Uzivatel getOwner() {
        return owner;
    }

    public void setHerci(List<Herec> herci) {
        this.herci = herci;
    }

    public List<Herec> getHerci() {
        return herci;
    }

    public void setReziseri(List<Reziser> reziseri) {
        this.reziseri = reziseri;
    }

    public List<Reziser> getReziseri() {
        return reziseri;
    }

    public void setStaty(List<Stat> staty) {
        this.staty = staty;
    }

    public List<Stat> getStaty() {
        return staty;
    }

    public void setZanry(List<Zanr> zanry) {
        this.zanry = zanry;
    }

    public List<Zanr> getZanry() {
        return zanry;
    }

    public void addUzivatel(Uzivatel uz, int hodnotil) {
        Hodnoceni hodnoceni = new Hodnoceni();
        hodnoceni.setUzivatel(uz);
        hodnoceni.setFilm(this);
        hodnoceni.setId_osoby(uz.getId_osoby());
        hodnoceni.setId_filmu(this.getId_filmu());
        hodnoceni.setHodnotil(hodnotil);

        this.hodnotici_uzivatele.add(hodnoceni);
        uz.getHodnocene_film().add(hodnoceni);
    }

    public Vector toVector() {
        Vector vec = new Vector();
        vec.add(this.getNazev_filmu());
        vec.add(this.getNazev_filmu());
        vec.add(this.getNazev_orig());
        vec.add(this.getRok());
        vec.add(this.getDelka());

        String zanry_string = "";
        for (int i = 0; i < getZanry().size(); i++) {
            Zanr zanr = getZanry().get(i);
            zanry_string += zanr.getNazev_zanru();
        }
        vec.add(zanry_string);

        String staty_string = "";
        for (int i = 0; i < getStaty().size(); i++) {
            Stat stat = getStaty().get(i);
            staty_string += stat.getNazev_statu();
        }
        vec.add(staty_string);

        return vec;
    }

    @Override
    public String toString() {
        String string = "";
        string += nazev_filmu + " (" + rok + ")";
        string += "\n";
        return string;
    }
}